package com.yxf.triangle;

import android.content.Context;
import android.opengl.GLSurfaceView;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
//1,静态导入OpenGL ES2.0包
import static android.opengl.GLES20.*;
//21,静态导入OpenGL的矩阵常用方法
import static android.opengl.Matrix.*;

public class MyRenderer implements GLSurfaceView.Renderer {

    //5,定义顶点坐标所需数字数量,二维图形只需要x,y两个 , 三维需要x,y,z三个.
    //我们先画个二维的三角形,所以顶点坐标所需数字常量设置为2.
    private static final int POSITION_COMPONENT_COUNT = 2;

    //24,注释掉注释6的修改
    /*//6,设置三角形的三个顶点坐标: 左下(-0.5f,0f),右下(0.5f,0f),中上(0f,0.5f)
    private float[] triangleVertices = {
            -0.5f,0f,
            0.5f,0f,
            0f,0.5f,
    };*/

    //25,给triangleVertices增加颜色数组
    private float[] triangleVertices = {
            -0.5f, 0f, 1f, 0f, 0f,//red
            0.5f, 0f, 0f, 0f, 1f,//blue
            0f, 0.5f, 1f, 1f, 1f,//white
    };

    //7,定义Native的浮点数储存所需字节数
    private static final int BYTES_PER_FLOAT = 4;
    //8,定义Native浮点数缓存的引用
    private final FloatBuffer vertexData;


    private Context context;

    //11,添加program对象Id定义
    private int program;

    //34.2,注释掉u_Color相关属性
    //14,定义u_Color和a_Position相关变量
    /*private static final String U_COLOR = "u_Color";
    private int uColorLocation;*/
    private static final String A_POSITION = "a_Position";
    private int aPositionLocation;

    //19,定义正交矩阵相关常量和变量
    private static final String U_MATRIX = "u_Matrix";
    private final float[] projectionMatrix = new float[16];
    private int uMatrixLocation;

    //26,定义a_Color常量及位置变量
    private static final String A_COLOR = "a_Color";
    private int aColorLocation;
    //27,定义颜色值所需数字数量
    private static final int COLOR_COMPONENT_COUNT = 3;
    //28,定义数组中相邻点的字节数跨距
    private static final int STRIDE = (POSITION_COMPONENT_COUNT +
            COLOR_COMPONENT_COUNT) * BYTES_PER_FLOAT;



    public MyRenderer(Context context) {
        this.context = context;

        //9,将三角形顶点数据储存到Native的浮点缓存中
        //注意必须使用ByteBuffer.allocateDirect而不是ByteBuffer.allocate,前者分配的才是不会被垃圾回收的本地内存
        vertexData = ByteBuffer.allocateDirect(triangleVertices.length * BYTES_PER_FLOAT)
                .order(ByteOrder.nativeOrder())
                .asFloatBuffer();
        vertexData.put(triangleVertices);
    }

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        //2,设置清空屏幕用的颜色
        glClearColor(0f, 1f, 0f, 0f);

        //9,读取shader源文件
        String vertexShaderSource = CommonUtils.readTextFromResource(context, R.raw.triangle_vertex_shader);
        String fragmentShaderSource = CommonUtils.readTextFromResource(context, R.raw.triangle_fragment_shader);

        //10,编译shader 源文件
        int vertexShader = CommonUtils.compileVertexShader(vertexShaderSource);
        int fragmentShader = CommonUtils.compileFragmentShader(fragmentShaderSource);

        //12,将shader添加进program,并获得Program的Id
        program = CommonUtils.linkProgram(vertexShader, fragmentShader);
        //13,使用这个program
        glUseProgram(program);

        //34.3,注释掉u_Color相关操作
        //15,获得u_Color和a_Position的位置
        //一个Uniform,一个Attribute别搞错了
        /*uColorLocation = glGetUniformLocation(program, U_COLOR);*/
        aPositionLocation = glGetAttribLocation(program, A_POSITION);

        //22,获取u_Matrix在顶点着色器中的位置
        uMatrixLocation = glGetUniformLocation(program, U_MATRIX);

        //29,增加对a_Color位置的获取
        aColorLocation = glGetAttribLocation(program, A_COLOR);

        //30,注释掉16的操作
        /*//16,根据a_Position的位置将顶点数据传给a_Position
        vertexData.position(0);
        glVertexAttribPointer(aPositionLocation, POSITION_COMPONENT_COUNT, GL_FLOAT,
                false, 0, vertexData);*/
        //31,更新跨距
        vertexData.position(0);
        glVertexAttribPointer(aPositionLocation, POSITION_COMPONENT_COUNT, GL_FLOAT,
                false, STRIDE, vertexData);

        //17,激活顶点数组
        glEnableVertexAttribArray(aPositionLocation);

        //32,传输颜色数据给a_Color
        vertexData.position(POSITION_COMPONENT_COUNT);
        glVertexAttribPointer(aColorLocation, COLOR_COMPONENT_COUNT, GL_FLOAT,
                false, STRIDE, vertexData);

        //33,激活颜色数组
        glEnableVertexAttribArray(aColorLocation);
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        //3,设置视口尺寸
        glViewport(0, 0, width, height);

        //20,创建正交投影矩阵
        final float aspectRatio = height / (float) width;
        orthoM(projectionMatrix, 0, -1f, 1f,
                -aspectRatio, aspectRatio, -1f, 1f);
    }

    @Override
    public void onDrawFrame(GL10 gl) {
        //4,根据步骤2设置的颜色清空屏幕,注意如果不清空会保留之前的绘制,所以这步一般是必要的
        glClear(GL_COLOR_BUFFER_BIT);

        //23,将正交投影矩阵传递给顶点着色器
        glUniformMatrix4fv(uMatrixLocation, 1, false, projectionMatrix, 0);

        //34.1,注释掉操作18
        /*//18,更新着色器中u_Color的值(r,g,b,a) = (255,255,255,255)
        glUniform4f(uColorLocation, 1f, 1f, 1f, 1f);*/
        //19,告诉OpenGL,画三角形,从开头读顶点数据开始读,读三个顶点
        glDrawArrays(GL_TRIANGLES, 0, 3);

    }
}
